package com.cea.papyrus.diagram.sequence.ui.dialogs;

import java.util.Iterator;

import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.BehaviorExecutionSpecification;
import org.eclipse.uml2.uml.BehavioredClassifier;
import org.eclipse.uml2.uml.ConnectableElement;
import org.eclipse.uml2.uml.Lifeline;
import org.eclipse.uml2.uml.OpaqueBehavior;
import org.eclipse.uml2.uml.Type;

import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.core.commands.UMLElementCreateCommand;
import com.cea.papyrus.core.editor.CommandStackUtils;

public class ExecutionSpecificationBehaviorOpaqueBehaviorTreeSelectionDialog extends Dialog {
	
	protected BehaviorExecutionSpecification execSpec;
	
	protected OpaqueBehavior opaqueBehavior;
	
	protected Button newButton;
	
	protected Label label;
	
	protected Tree SFTree;
	
	
	public ExecutionSpecificationBehaviorOpaqueBehaviorTreeSelectionDialog (Shell parent, BehaviorExecutionSpecification execSpec) {
		super (parent);
		this.execSpec = execSpec;
		// add the resize ability to the window
		setShellStyle(SWT.RESIZE | super.getShellStyle());
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createDialogArea(Composite parent){
		Composite comp=(Composite)super.createDialogArea(parent);
	
		label = new Label(comp, SWT.NONE);
		label.setText("Select an existing opaque behavior or create a new one:");
		label.setToolTipText("Behaviors already attached to a specification are not applicable thus not listed");
		label.setLayoutData(new GridData());
		
		newButton = new Button(comp, SWT.NONE);
		newButton.setText("New OpaqueBehavior");
		newButton.setLayoutData(new GridData(200, 25));

		SFTree = new Tree(comp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL);

		BehavioredClassifier tempClassifier = null;		
		Lifeline coveredLifeline = execSpec.getStart().getCovereds().get(0);
		if (coveredLifeline.getRepresents() != null) {
			ConnectableElement represented = coveredLifeline.getRepresents();
			if (represented.getType() != null) {
				Type type = represented.getType();
				if (type instanceof BehavioredClassifier) {
					tempClassifier = (BehavioredClassifier) type;
				}				
			}
		}
		final BehavioredClassifier classifier = tempClassifier;
		if (classifier != null) {

			// get owned opaque behaviors
			Iterator<Behavior> iter = classifier.getOwnedBehaviors().iterator();
			while(iter.hasNext()){
				Behavior currentBehavior = iter.next();
				if (currentBehavior instanceof OpaqueBehavior) {
					TreeItem opaqueBehaviorItem = new TreeItem(SFTree, SWT.SINGLE);
					opaqueBehaviorItem.setText(currentBehavior.getName());
					opaqueBehaviorItem.setData(currentBehavior);
					opaqueBehaviorItem.setImage(PapyrusPlugin.UML_LABEL_PROVIDER.getImage(currentBehavior));
				}
			}
		} else {
			newButton.setEnabled(false);
		}
			
		SFTree.setLayoutData(new GridData(550, 300));
		
		SFTree.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e){
				TreeItem[] selection = SFTree.getSelection();
				if(selection[0].getData() instanceof OpaqueBehavior){
					opaqueBehavior = (OpaqueBehavior)selection[0].getData();
				}
			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		
		
		newButton.addMouseListener(new MouseListener(){
			public void mouseDoubleClick(MouseEvent e) {
			}

			public void mouseDown(MouseEvent e) {
			}

			public void mouseUp(MouseEvent e) {

				// creation command
				final UMLElementCreateCommand command = 
					new UMLElementCreateCommand(OpaqueBehavior.class, classifier);
				
				CommandStack commandStack = CommandStackUtils.getCommandStack();
				if(commandStack!= null) {
					commandStack.execute(command);
				}

				OpaqueBehavior newOpaqueBehavior = (OpaqueBehavior)command.getElement();
				// add the new OpaqueBehavior
				TreeItem opaqueBahaviorItem = new TreeItem(SFTree, SWT.SINGLE);
				opaqueBahaviorItem.setText(newOpaqueBehavior.getName());
				opaqueBahaviorItem.setData(newOpaqueBehavior);
				opaqueBahaviorItem.setImage(PapyrusPlugin.UML_LABEL_PROVIDER.getImage(newOpaqueBehavior));
				
				SFTree.setSelection(opaqueBahaviorItem);
				opaqueBehavior = (OpaqueBehavior)opaqueBahaviorItem.getData();

			}

		});
		
		return comp;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	protected void configureShell(Shell shell) {
	      super.configureShell(shell);
	      shell.setText(execSpec.getName()+": Behavior Selection");
	}

	/**
	 * Returns the elements to import.
	 * 
	 * @return 
	 */
	public OpaqueBehavior getResult(){
		return opaqueBehavior;
	}

}